using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using CommLayer;
using System.IO;
using Tamir.IPLib;
using Tamir.IPLib.Packets;
using System.Net.NetworkInformation;
using System.Diagnostics;
using Magnolia;

namespace TestApp
{
    class Program
    {
        static StringComInt[] m_myCommInt;
       
        /// <summary>
        /// Main loop
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            int a = 1;
            if (args.Length == 0)
            {
                Console.WriteLine();
                Console.WriteLine("Test App: ");
                Console.WriteLine("1. Data communication");
                Console.WriteLine("2. Sync communication");
                a = int.Parse(Console.ReadLine());
            }

            if (a == 2)
            {
                
                /* Retrieve the device list */
                PcapDeviceList devices = SharpPcap.GetAllDevices();

                /*If no device exists, print error */
                if (devices.Count < 1)
                {
                    Console.WriteLine("No device found on this machine");
                    return;
                }

                Console.WriteLine();
                Console.WriteLine("The following devices are available on this machine:");
                Console.WriteLine("----------------------------------------------------");
                Console.WriteLine();

                int i = 0;

                /* Scan the list printing every entry */
                foreach (PcapDevice dev in devices)
                {
                    /* Description */
                    Console.WriteLine("{0}) {1}", i, dev.PcapDescription);
                    i++;
                }

                Console.WriteLine();
                Console.Write("-- Please choose a device to capture: ");
                i = int.Parse(Console.ReadLine());

                PcapDevice device = devices[i];

                m_myCommInt[0] = new UdpSniffer(device);
                m_myCommInt[0].Port = 5561;
                m_myCommInt[0].InitializeClient(logStringConnect, logString, logStringException);

            }
            else if (a == 1)
            {
                m_myCommInt = new StringComTcpIp[3];
                // initialize log
                AppContext.AppTraceSwitch = new TraceSwitch("Magnolia", "Magnolia trace switch");

                // server
                if (args.Length == 0)
                {
                    
                    // see all NICs
                    Console.WriteLine("Server");
                    Console.WriteLine("Choose a connection to listen on");
                    int i = 0;
                    foreach (NetworkInterface nic in
                      NetworkInterface.GetAllNetworkInterfaces())
                    {
                        Console.WriteLine(i.ToString() + "." + nic.Name);
                        foreach (UnicastIPAddressInformation addrInfo in
                            nic.GetIPProperties().UnicastAddresses)
                        {
                            Console.WriteLine("\t" + addrInfo.Address);
                        }
                        i++;
                    }
                    // get the selection
                    int s = int.Parse(Console.ReadLine());
                    NetworkInterface adapter = NetworkInterface.GetAllNetworkInterfaces()[s];
                    // set and go
                    m_myCommInt[0] = new StringComTcpIp();
                    m_myCommInt[0].IPAddress = adapter.GetPhysicalAddress().ToString();
                    m_myCommInt[0].Port = 7001;

                    m_myCommInt[0].InitializeServer(logStringConnect, logString, logStringException);

//                    TestSend();
                                       
                }
                else // client
                {
                    Console.WriteLine("Client");
                    for (int i = 0; i < 3; i++)
                    {
                        m_myCommInt[i] = new StringComTcpIp();
                        m_myCommInt[i].IPAddress = args[i];
                        m_myCommInt[i].Port = 7001;
                        Console.WriteLine("Connect to " + m_myCommInt[i].IPAddress + " port " + m_myCommInt[i].Port.ToString());
                        m_myCommInt[i].InitializeClient(logStringConnect, logString, logStringException);
                        //Thread.Sleep(1000);
                    }
                    TestSend("");
                }

                // test sending
               /* string msg = "";
                int i = 0;
                while (i++ < 15)
                {

                    msg += "1234567890";

                }

                m_myCommInt.SendString(msg);*/
                while (true) { System.Threading.Thread.Sleep(1); }
            }

            
    
        }

        /// <summary>
        /// report back
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="str"></param>
        public static void logStringException(DateTime time, string str)
        {
            // create a writer and open the file
            string timemsg = time.Ticks.ToString();
            if (str.Length > 2048)
            {
                TextWriter tw = new StreamWriter("c:\\temp\\magtest" + timemsg + ".txt");
                // write a line of text to the file
                tw.Write(str);
                //// close the stream
                tw.Close();
            }

            Console.WriteLine("{0}:{1}:{2},{3} , {4}",
                time.Hour, time.Minute, time.Second, time.Millisecond, str.Length > 2048 ? "long str" : str);

         }

        /// <summary>
        /// report back
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="str"></param>
        public static void logString(DateTime time,string str)
        {
            // create a writer and open the file
            string timemsg = time.Ticks.ToString();
            if (str.Length > 2048)
            {
                TextWriter tw = new StreamWriter("c:\\temp\\magtest" + timemsg + ".txt");
                // write a line of text to the file
                tw.Write(str);
                //// close the stream
                tw.Close();
            }

            Console.WriteLine("{0}:{1}:{2},{3} , {4}",
                time.Hour, time.Minute, time.Second, time.Millisecond, str.Length > 2048 ? "long str": str);
            
            //report back - not on connection
            if (!m_myCommInt[0].IsClient)
            {
                //Trace.WriteLineIf(AppContext.AppTraceSwitch.TraceInfo, XYNetCommon.GetTimeString() + "server sending 'got it'");
                if (str.StartsWith("Ping"))
                {
                    Thread.Sleep(2000);
                    m_myCommInt[0].QueueSendString("server got " + str + " at " + time.Hour.ToString() + ":" + time.Minute.ToString() + ":" + time.Second.ToString() + ":" + time.Millisecond);
                }
            }
            else
            {
                Trace.WriteLineIf(AppContext.AppTraceSwitch.TraceInfo, XYNetCommon.GetTimeString() + "client sending 'got it'");
                if (str.StartsWith("SPing"))
                    m_myCommInt[0].QueueSendString("client got " + str + " at " + time.Hour.ToString() + ":" + time.Minute.ToString() + ":" + time.Second.ToString() + ":" + time.Millisecond);

            }
        }

        /// <summary>
        /// report back
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="str"></param>
        public static void logStringConnect(DateTime time, string str)
        {
            // create a writer and open the file
            string timemsg = time.Ticks.ToString();
            if (str.Length > 2048)
            {
                TextWriter tw = new StreamWriter("c:\\temp\\magtest" + timemsg + ".txt");
                // write a line of text to the file
                tw.Write(str);
                //// close the stream
                tw.Close();
            }

            Console.WriteLine("{0}:{1}:{2},{3} , {4}",
                time.Hour, time.Minute, time.Second, time.Millisecond, str.Length > 2048 ? "long str" : str);

            if (m_myCommInt[0].IsClient)
            {
//                TestSend("");
            }
            //else TestSend("S");

        }

        /// <summary>
        /// Testing
        /// </summary>
        static void TestSend(string prefix)
        {
            // test
            int i = 0;
            while (true)
            {
                string str = "";
                // create a writer and open the file
                
                //TextReader tw = new StreamReader("c:\\temp\\magtest.txt");//;C:\\Magnolia\\Medialon\\test4.txt");//
                ////// write a line of text to the file
                //str = tw.ReadToEnd();
                ////// close the stream
                //tw.Close();
                i++;
                for (int c = 0; c <= 2; c++)
                {
                    Console.WriteLine(XYNetCommon.GetTimeString() + "Send " + "Ping " + i.ToString() + " on connection " + c.ToString());
                    m_myCommInt[c].QueueSendString(prefix + "Ping " + i.ToString());//"test frame " + i.ToString() + "\n" + str);
                    System.Threading.Thread.Sleep(3000);
                }
            }
        }
    }
    
}
